﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCityPlayerViewExt.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-09-17
//    @Email			:    445267987@qq.com
//    @Module           :    NFCityPlayerViewExt
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFCityPlayerViewExt.h"

#include "ConstantDescEx.h"
#include "NFCityPlayer.h"
#include "NFCityPlayerUtil.h"
#include "NFCityWorldObjectFunc.h"
#include "NFLogicCommon/NFDistanceUtil.h"

NFCityPlayerViewExt::NFCityPlayerViewExt()
{
    if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
    {
        CreateInit();
    }
    else
    {
        ResumeInit();
    }
}

NFCityPlayerViewExt::~NFCityPlayerViewExt()
{
}

int NFCityPlayerViewExt::CreateInit()
{
    m_iMaxViewLimit = 0;
    m_bIsGBView = false;
    m_iGBViewSplitIndex = 0;
    m_ullRoleId = 0;
    return 0;
}

int NFCityPlayerViewExt::ResumeInit()
{
    return 0;
}

void NFCityPlayerViewExt::SetMaxViewNum(int iMaxNum)
{
    m_iMaxViewLimit = std::min(iMaxNum, (int)MAX_VIEW_PLAYER_NUM);
}

void NFCityPlayerViewExt::SetGBView(bool bSet)
{
    m_bIsGBView = bSet;
    m_tvGBRefreshTime = NF_ADJUST_TIMENOW();
    if (m_bIsGBView)
    {
        m_oViewHash.sort_list(std::greater<int>());
    }
}

int NFCityPlayerViewExt::RefreshGBViewList(NFCityPlayer* pPlayer)
{
    CHECK_NULL(m_ullRoleId, pPlayer);

    if (!m_bIsGBView || m_oViewHash.size() == 0)
    {
        return 0;
    }

    if ((NF_ADJUST_TIMENOW() - m_tvGBRefreshTime) < DEFAULT_GB_VIEW_REFRESH_INTERNAL)
    {
        return 0;
    }

    for (auto iter = m_oViewHash.list_begin(); iter != m_oViewHash.list_end();)
    {
        NFCityPlayer* pViewPlayer = NFCityPlayerUtil::GetPlayerByRoleID(iter->first);
        if (pViewPlayer)
        {
            int iAllieNum = 0;
            int iEnemyNum = 0;
            iter->second = CalcGBViewScore(pPlayer, pViewPlayer, iAllieNum, iEnemyNum);
            ++iter;
        }
        else
        {
            iter = m_oViewHash.erase(iter);
        }
    }

    m_oViewHash.sort_list([](const int a, const int b)
    {
        return a > b;
    });

    return 0;
}

int NFCityPlayerViewExt::RemoveFromViewList(uint64_t ullRoleID)
{
    if (IsInViewList(ullRoleID))
    {
        m_oViewHash.erase(ullRoleID);
        LOG_INFO(m_ullRoleId, "remove view:{}", ullRoleID);
    }

    return 0;
}

int NFCityPlayerViewExt::AddToViewList(uint64_t ullRoleID, int iScore)
{
    if (m_oViewHash.full())
    {
        LOG_ERR(m_ullRoleId, -1, "view is full! roleId:{} score:{}", ullRoleID, iScore);
        return -1;
    }

    if (IsInViewList(ullRoleID))
    {
        return -1;
    }

    if (m_bIsGBView)
    {
        AddGBView(ullRoleID, iScore);
    }
    else
    {
        AddNormalView(ullRoleID, iScore);
    }

    LOG_INFO(m_ullRoleId, "add view, roleId:{} iScore:{}", ullRoleID, iScore);

    return 0;
}

bool NFCityPlayerViewExt::IsInViewList(uint64_t ullRoleID)
{
    if (m_oViewHash.find(ullRoleID) != m_oViewHash.end())
    {
        return true;
    }

    return false;
}

int NFCityPlayerViewExt::IteratorViewList(NFICityWorldObjectFunc* pFunc)
{
    CHECK_NULL(0, pFunc);

    for (auto iter = m_oViewHash.list_begin(); iter != m_oViewHash.list_end();)
    {
        NFCityPlayer* pPlayer = NFCityPlayerUtil::GetPlayerByRoleID(iter->first);
        if (pPlayer)
        {
            pFunc->DoFunc(pPlayer);
            ++iter;
        }
        else
        {
            iter = m_oViewHash.erase(iter);
        }
    }

    return 0;
}

bool NFCityPlayerViewExt::IsTeamLeaderInView(NFCityPlayer* pPlayer)
{
    if (!pPlayer)
        return false;

    return IsInViewList(pPlayer->GetRoleID());
}

int NFCityPlayerViewExt::RemoveFromEnterViewList(uint64_t ullRoleID)
{
    m_oEnterViewList.erase(ullRoleID);
    return 0;
}

int NFCityPlayerViewExt::AddToEnterViewList(uint64_t ullRoleID)
{
    if (m_oEnterViewList.full())
    {
        LOG_ERR(0, -1, "enter view is full! roleId:{}", ullRoleID);
        return -1;
    }

    m_oEnterViewList.insert(ullRoleID);

    return 0;
}

int NFCityPlayerViewExt::IteratorEnterViewList(NFICityWorldObjectFunc* pFunc)
{
    CHECK_NULL(0, pFunc);

    for (auto iter = m_oEnterViewList.begin(); iter != m_oEnterViewList.end();)
    {
        NFCityPlayer* pPlayer = NFCityPlayerUtil::GetPlayerByRoleID(*iter);
        if (pPlayer)
        {
            pFunc->DoFunc(pPlayer);
            ++iter;
        }
        else
        {
            iter = m_oEnterViewList.erase(iter);
        }
    }

    return 0;
}

bool NFCityPlayerViewExt::IsViewListFull() const
{
    return m_oViewHash.size() >= (uint32_t)(m_iMaxViewLimit - MAX_TEAM_MEMBER_NUM);
}

bool NFCityPlayerViewExt::IsEnterViewListFull()
{
    return m_oEnterViewList.size() >= (uint32_t)(MAX_PLAYER_ENTER_VIEW_NUM - MAX_TEAM_MEMBER_NUM);
}

int NFCityPlayerViewExt::AddNormalView(uint64_t ullRoleID, int iScore)
{
    m_oViewHash[ullRoleID] = iScore;
    return 0;
}

int NFCityPlayerViewExt::AddGBView(uint64_t ullRoleID, int iScore)
{
    m_oViewHash.emplace_list_sorted_comp(std::greater<int>(), ullRoleID, iScore);
    return 0;
}

int NFCityPlayerViewExt::CalcGBViewScore(NFCityPlayer* pPlayer, NFCityPlayer* pViewPlayer, int& iAllieNum, int& iEnemyNum)
{
    int iScore = 0;

    int iDistance = ConstantDescEx::Instance()->GetValue(proto_ff::EN_CONST_GUILD_BATTLE_ATTCK_RANGE) * 10000;
    if (NFDistanceUtil::IsInRange(pPlayer->GetPosition(), pViewPlayer->GetPosition(), iDistance))
    {
        iScore += EN_GB_VIEW_SCORE_LV4;
    }

    if (!pViewPlayer->GetBattleExt()->IsInBattle())
    {
        iScore += EN_GB_VIEW_SCORE_LV3;
    }

    int iLineNum = MAX_GB_VIEW_PLAYER_NUM / 2;
    if (pPlayer->GetGuildID() == pViewPlayer->GetGuildID())
    {
        iScore = iAllieNum > iLineNum ? iScore + iLineNum - iAllieNum : 0;
        ++iAllieNum;
    }
    else
    {
        iScore = iEnemyNum > iLineNum ? iScore + iLineNum - iEnemyNum : 0;
        ++iEnemyNum;
    }

    return 0;
}
